# frozen_string_literal: true

module Wpxf
  module Cli
    # Methods for handling output to the screen.
    module Output
      def initialize
        super
        self.indent = '  '
        self.indent_level = 1
      end

      def indent_cursor(level = 1)
        self.indent_level += level
        yield
        self.indent_level -= level
      end

      def remove_new_lines_and_wrap_text(value, padding = 0, width = 78)
        wrap_text(value.tr("\n", ''), padding, width)
      end

      def wrap_text(value, padding = 0, width = 78)
        value.gsub(/(.{1,#{width}})(\s+|\Z)/, "\\1\n#{indent * indent_level}#{' ' * padding}").chomp
             .gsub(/\s+$/, '')
      end

      def indent_without_wrap(value)
        value.gsub(/\n/, "\n#{indent * indent_level}")
      end

      def print_std(msg)
        puts "#{indent * indent_level}#{msg}"
      end

      def print_info(msg)
        print "#{indent * indent_level}[-] ".light_blue
        puts wrap_text(msg, 4, 90)
      end

      def print_good(msg)
        print "#{indent * indent_level}[+] ".green
        puts wrap_text(msg, 4, 90)
      end

      def print_bad(msg)
        print "#{indent * indent_level}[!] ".red
        puts wrap_text(msg, 4, 90)
      end

      def print_warning(msg)
        print "#{indent * indent_level}[!] ".yellow
        puts wrap_text(msg, 4, 90)
      end

      def print_table(data, pad_with_new_lines = false)
        puts if pad_with_new_lines

        col_widths = calculate_col_widths(data)
        print_table_header data, col_widths

        (1..data.length - 1).each do |i|
          print_table_row(data[i], col_widths)
          puts
        end

        puts if pad_with_new_lines
      end

      def print_table_header(data, col_widths)
        print_table_row data[0], col_widths
        puts
        print_header_separator col_widths
        puts
      end

      def calculate_col_widths(data)
        widths = {}
        data.each do |row|
          row.keys.each do |col|
            if widths[col].nil? || row[col].to_s.length > widths[col]
              widths[col] = row[col].to_s.length
            end
          end
        end
        widths
      end

      def print_header_separator(widths)
        separators = {}
        widths.keys.each do |col|
          separators[col] = '-' * widths[col]
        end

        print_table_row(separators, widths)
      end

      def print_table_row(data, widths)
        print indent * indent_level
        data.keys.each do |col|
          padding = widths[col] - data[col].to_s.length
          print "#{data[col]}#{' ' * padding}   "
        end
      end

      attr_accessor :indent
      attr_accessor :indent_level
    end
  end
end
